﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;

using BeachRunner.BeachRunner;
using BeachRunner.Utility;
using BeachRunner.Entity;
using BeachRunner.Tileengine;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
using BeachRunner.Menu;

namespace BeachRunner.Level
{
    /// <summary>
    /// Verwaltet die Level und hält allgemeine Level Ressourcen (Tileset, Pausemenü)
    /// 
    /// Autor: Arne Blumentritt
    /// </summary>
    public class LevelManager
    {
        // Pausemenü
        public bool IsPause { get; set; }
        private Texture2D buttonHeadBg;
        private Texture2D buttonBlueBg;
        private Texture2D buttonLightblueBg;
        private Button buttonResume;
        private Button buttonMainmenu;
        private Button buttonHead;
        private bool canQuitPausemenu;

        // Allgemeines Tileset
        private Tileset tileset;
        private Texture2D tilesetTexture;
        private short[] nextTile;
        private short[] tileDuration;

        // Leveldaten
        private Level level1;
        private Level level2;
        private Level level3;
        private Level level4;
        public Game1.Maps CurrentLevelID { get; set; }
        public Level CurrentLevel { get; set; }

        public LevelManager()
        {
            this.level1 = new Level(Game1.Maps.Level1, 50, 25, 0, 0, 1.0f);
            this.level2 = new Level(Game1.Maps.Level2, 25, 25, 0, 0, 1.5f);
            this.level3 = new Level(Game1.Maps.Level3, 25, 50, 25, 0, 2f);
            this.level4 = new Level(Game1.Maps.Level4, 100, 0, 50, 60000, 1.5f, false, true);
        }

        public void LoadContent(ContentManager contentManager)
        {
            // Allgemeinen Levelcontent laden
            // ==============================
            // Textur
            tilesetTexture = contentManager.Load<Texture2D>("gfx//tilesets//tileset");

            // Jedes animierte Tile bekommt einen Nachfolger zugewiesen, nicht animierte bekommen -1 zugewiesen.
            nextTile = new short[] {    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            91,92,93,94,95,96,97,90,-1,-1,
                                            -1,-1,-1,106,-1,-1,107,103,-1,-1,
                                            111,112,113,114,115,116,117,110,-1,-1, 
                                            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                            131,132,133,134,135,130,-1,-1,-1,-1 };

            // Jedes animierte Tile bekommt eine Anzeigedauer zugewiesen, nicht animierte bekommen -1 zugewiesen.
            tileDuration = new short[] {    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                200,200,200,200,200,200,200,200,-1,-1,
                                                -1,-1,-1,200,-1,-1,200,200,-1,-1,
                                                200,200,200,200,200,200,200,200,-1,-1, 
                                                -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                                                100,100,100,100,100,100,-1,-1,-1,-1 };

            // Tileset
            tileset = new Tileset(tilesetTexture, nextTile, tileDuration);

            // Pausemenü
            buttonHeadBg = contentManager.Load<Texture2D>("gfx//mainmenu//head-bg");
            buttonBlueBg = contentManager.Load<Texture2D>("gfx//mainmenu//blue_button");
            buttonLightblueBg = contentManager.Load<Texture2D>("gfx//mainmenu//lightblue_button");
            
            buttonHead = new Button(new Vector2(Game1.RES_X / 2 - buttonHeadBg.Width / 2, 70), buttonHeadBg, "GAME PAUSED", Game1.Font_l);
            buttonMainmenu = new Button(new Vector2(15, 335), buttonBlueBg, "MAIN MENU", Game1.Font_xl);
            buttonResume = new Button(new Vector2(Game1.RES_X - 15 - buttonLightblueBg.Width, 335), buttonLightblueBg, "RESUME", Game1.Font_xl);
            

            // Spezifischen Levelcontent laden
            // ===============================
            level1.LoadContent(contentManager, tileset);
            level2.LoadContent(contentManager, tileset);
            level3.LoadContent(contentManager, tileset);
            level4.LoadContent(contentManager, tileset);
        }

        /// <summary>
        /// Initialisierung bei Levelstart
        /// </summary>
        public void Init()
        {
            //    // die momentane Karte setzen
            //    Game1.CurrentMap = map;

            switch (CurrentLevelID)
            {
                case Game1.Maps.Level1:
                    CurrentLevel = level1;
                    break;
                case Game1.Maps.Level2:
                    CurrentLevel = level2;
                    break;
                case Game1.Maps.Level3:
                    CurrentLevel = level3;
                    break;
                case Game1.Maps.Level4:
                    CurrentLevel = level4;
                    break;
            }
            CurrentLevel.Init();

            canQuitPausemenu = false;
        }

        public void Update()
        {
            // Bei Drücken des Zurückbuttons oder Verschieben der App in den Hintergrund, Wechsel in den Pausemodus
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                IsPause = true;

            // Im Pausemodus
            if (IsPause)
            {
                buttonMainmenu.Update();
                buttonResume.Update();

                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Released)
                    canQuitPausemenu = true;

                // Bei erneutem Drücken des Zurückbuttons oder Klicken auf den Button "Hauptmenu", beenden des Levels
                if ((canQuitPausemenu && GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) || buttonMainmenu.IsClicked)
                {
                    IsPause = false;
                    MediaPlayer.Stop();
                    Game1.GameState = Game1.GameStates.Menu;
                    Game1.MenuManager.CurrentPage = Game1.MenuManager.MainMenuPage;
                    Game1.ScoreManager.Scores = 0;
                }

                // Bei drücken des Buttons Resume, beenden des Pausemenüs
                if (buttonResume.IsClicked)
                {
                    IsPause = false;
                    canQuitPausemenu = false;
                    // 150ms Toucheingabe blockieren, damit der Druck auf den Resume Button nicht zu einem Sprung führt
                    IOTouchControl.BlockTouchTimer = 150;
                }

            }
            // Kein Pausemodus
            else
            {
                // Das Tileset animiert sich selber.
                tileset.Update();

                CurrentLevel.Update();
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            // Hintergrund wird gezeichnet
            Game1.BackgroundManager.Draw(spriteBatch);

            CurrentLevel.Draw(spriteBatch);

            // Im Pausemodus
            if (IsPause)
            {
                buttonHead.Draw(spriteBatch);
                buttonMainmenu.Draw(spriteBatch);
                buttonResume.Draw(spriteBatch);
            }
        }
    }
}
